package service

import (
	"gitee.com/kristas/booting-go/framework"
	"gitee.com/kristas/booting-go/framework/common/util/list"
	"gitee.com/kristas/booting-go/framework/core/statement"
	"gitee.com/kristas/booting-go/framework/core/statement/types"
	"gitee.com/kristas/booting-go/framework/web"
	"gitee.com/kristas/booting-go/framework/web/controller"
	"gitee.com/kristas/booting-go/framework/web/resp"
	"reflect"
	"sort"
)

func init() {
	framework.Component(new(RouteServiceImpl))
}

type RouteService interface {
	statement.Service
	Apis() resp.Response
}

type RouteServiceImpl struct {
	types.Service `service:"RouteService"`
	Controllers   []web.Controller `wire:""`                      //使用切片接口类型注入所有实现类
	AppName       string           `value:"application.app_name"` //使用value标签实现配置文件注入
}

type ControllerModel struct {
	Controller string
	APIs       []Api
}

type Api struct {
	Method string
	Url    string
	Params []Param
}

type Param struct {
	Name   string
	Source string
	Type   string
}

func (t *RouteServiceImpl) Apis() resp.Response {
	var controllers []ControllerModel
	sort.Slice(t.Controllers, func(i, j int) bool {
		return t.Controllers[i].Group() < t.Controllers[j].Group()
	})
	list.NewList(t.Controllers).ForEach(func(i int) {
		c := t.Controllers[i]
		ctr := ControllerModel{Controller: reflect.ValueOf(c).Type().Elem().String()}
		controller.RestApiExtract(c,
			func(apiInfo web.ApiInfo, function web.ServiceMethod) {
				var params []Param
				for _, param := range apiInfo.GetParams() {
					params = append(params, Param{
						Name:   param.GetName(),
						Source: param.GetSource(),
						Type:   param.GetType().String(),
					})
				}
				ctr.APIs = append(ctr.APIs, Api{
					Method: apiInfo.GetHttpMethod(),
					Url:    apiInfo.GetURL(),
					Params: params,
				})
			})
		controllers = append(controllers, ctr)
	})
	model := resp.Model()
	model.SetView("./resources/apis.html")
	model.SetAttributes("Title", t.AppName)
	model.SetAttributes("Routers", controllers)
	return model.Response()
}
